#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

typedef enum {
    ET1Measure = 1,           // 单个距离
    ET2Measure = 2,           // 两个距离，面积
    ET3Measure = 3,           // 三个距离，体积
    ETriangle1 = 4,           // 三角类型1，通过斜边和一个直角边求另一个直角边
    ETriangle2 = 5,           // 三角类型2，通过两个斜边和高求底
    ETriangle3 = 6,           // 三角类型3，通过两个同侧斜边和高求距离
    ETriangle4 = 7,           // 三角类型4，通过一个角度和一个斜边求两个直角边
} EMeasure;


typedef struct TMeasure_ {
    EMeasure type;
    int year;
    char month;
    char day;
    char hour;
    char min;
} TMeasure;

typedef struct T1Measure_ {
    TMeasure base;
    int distance;
} T1Measure;

typedef struct T2Measure_ {
    TMeasure base;
    int distance1;
    int distance2;
    int result;
} T2Measure;

typedef struct T3Measure_ {
    TMeasure base;
    int distance1;
    int distance2;
    int distance3;
    int result;
} T3Measure;

typedef struct Triangle1_ {
    TMeasure base;
    int distance1;
    int distance2;
    int result;
} Triangle1;

typedef struct Triangle2_ {
    TMeasure base;
    int distance1;
    int distance2;
    int distance3;
    int result;
} Triangle2;

typedef struct Triangle3_ {
    TMeasure base;
    int distance1;
    int distance2;
    int distance3;
    int result;
} Triangle3;

typedef struct Triangle4_ {
    TMeasure base;
    int angle;
    int distance;
    int result1;
    int result2;
} Triangle4;

#define TOTAL_COUNT 10
int tMeasureDataCount = 0;
int nHeadIndex = 0;
static TMeasure *measureDataArr[TOTAL_COUNT] = {0};
int saveMeasureData()
{
    FILE *fp = fopen("measures.dat", "wb");
    if (fp == NULL) {
        return -1;
    }

    // 写入总数
    fwrite(&tMeasureDataCount, 1, sizeof(tMeasureDataCount), fp);

    for (int i = 0; i < tMeasureDataCount; i++) {
        // 加入分割 ####
        fwrite("####", 4, 1, fp);
        int index = (nHeadIndex + i) % TOTAL_COUNT;
        TMeasure *data = measureDataArr[index];
        switch(data->type) {
            case ET1Measure:
                fwrite(data, 1, sizeof(T1Measure), fp);
                break;
            case ET2Measure:
                fwrite(data, 1, sizeof(T2Measure), fp);
                break;
            case ET3Measure:
                fwrite(data, 1, sizeof(T3Measure), fp);
                break;
            case ETriangle1:
                fwrite(data, 1, sizeof(Triangle1), fp);
                break;
            case ETriangle2:
                fwrite(data, 1, sizeof(Triangle2), fp);
                break;
            case ETriangle3:
                fwrite(data, 1, sizeof(Triangle3), fp);
                break;
            case ETriangle4:
                fwrite(data, 1, sizeof(Triangle4), fp);
                break;
            default:
                break;
        }
    }

    fclose(fp);
    return tMeasureDataCount;
}

int loadMeasureData()
{
    FILE *fp = fopen("measures.dat", "rb");
    if (fp == NULL) {
        return -1;
    }

    tMeasureDataCount = 0;
    nHeadIndex = 0;
    memset(measureDataArr, 0, sizeof(measureDataArr));

    int count = 0;
    char buf[5];
    fread(&count, 1, sizeof(count), fp);
    for (int i = 0; i < count; i++) {
        // 读取4个直接 ####
        fread(buf, 4, 1, fp ); buf[4] = 0;
        EMeasure type;
        fread(&type, 1, sizeof(EMeasure), fp);
        fseek(fp, -sizeof(EMeasure), SEEK_CUR);
        printf("read index:%d, splitter: %s, type: %d, filepos: 0x%x\n", i, buf, type, ftell(fp));
        switch(type) {
            case ET1Measure: {
                T1Measure data;
                fread(&data, 1, sizeof(T1Measure), fp);
                break;
            }
            case ET2Measure: {
                T2Measure data;
                fread(&data, 1, sizeof(T2Measure), fp);
                break;
            }
            case ET3Measure: {
                T3Measure data;
                fread(&data, 1, sizeof(T3Measure), fp);
                break;
            }
            case ETriangle1: {
                Triangle1 data;
                fread(&data, 1, sizeof(Triangle1), fp);
                break;
            }
            case ETriangle2: {
                Triangle2 data;
                fread(&data, 1, sizeof(Triangle2), fp);
                break;
            }
            case ETriangle3: {
                Triangle3 data;
                fread(&data, 1, sizeof(Triangle3), fp);
                break;
            }
            case ETriangle4:  {
                Triangle4 data;
                fread(&data, 1, sizeof(Triangle4), fp);
                break;
            }
            default:
                break;
        }
    }

    fclose(fp);

    return tMeasureDataCount;
}

void doSave()
{
    T1Measure *data1 = (T1Measure*)malloc(sizeof(T1Measure));
    data1->base.type = ET1Measure;
    data1->distance = 0x1234;

    T2Measure *data2 = (T2Measure*)malloc(sizeof(T2Measure));
    data2->base.type = ET2Measure;
    data2->distance1 = 0x5678;
    data2->distance2 = 0x1212;
    data2->result = 0x3333;
    Triangle1 *data3 = (Triangle1*)malloc(sizeof(Triangle1));
    data3->base.type = ETriangle1;
    data3->distance1 = 0x5678;
    data3->distance2 = 0x1212;
    data3->result = 0x3333;

    tMeasureDataCount = 5;
    measureDataArr[0] = (TMeasure *)data1;
    measureDataArr[1] = (TMeasure *)data1;
    measureDataArr[2] = (TMeasure *)data2;
    measureDataArr[3] = (TMeasure *)data2;
    measureDataArr[4] = (TMeasure *)data3;

    saveMeasureData();

    free(data1);
    free(data2);
}

void doLoad()
{
    loadMeasureData();
    printf("%d\n", sizeof(measureDataArr));
}

/// 保存简单数据到文件
void doSaveData()
{
    FILE *fp = fopen("test.dat", "wb");
    if (fp == NULL) {
        return;
    }
    char a = -1;
    char b = 3;
    u_char c = -3;
    fwrite(&a, 1, 1, fp);
    printf("1: filepos: 0x%x\n",  ftell(fp));
    fflush(fp);
    fwrite(&b, 1, 1, fp);
    printf("1: filepos: 0x%x\n",  ftell(fp));
    fwrite(&c, 1, 1, fp);
    fwrite(&a, 1, 1, fp);

    int d = 0x12345678;
    fwrite(&d, 4, 1, fp);

    fclose(fp);
}

int main(int argc, char *argv[])
{

    int op = 3;
    switch (op) {
    case 0:
        doSave();
        break;
    case 1:
        doLoad();
        break;
    case 2:
        doSaveData();
        break;
    case 3:
    {
        char *str="abc";
        printf("%p, %p, %p\n", str, &str, &str[0]);
        break;
    }
    default:
        break;
    }

    return 0;
}
